import { getToken } from '@ibiz-template/core';
import { ModelUtil } from '@ibiz-template/model';
import { Suspense, useEffect, useState } from 'react';
import {
  Navigate,
  RouteObject,
  useLocation,
  useRoutes,
} from 'react-router-dom';

export interface AuthGuardProps {
  routes: RouteObject[];
}

/**
 * 初始化模型
 *
 * @author chitanda
 * @date 2022-07-20 20:07:58
 * @return {*}  {Promise<void>}
 */
async function loadModel(): Promise<void> {
  await ModelUtil.create(async modelPath => {
    const url = `./model${modelPath}`;
    try {
      const res = await ibiz.net.getModel(url);
      if (res.ok) {
        return res.data;
      }
    } catch (error) {
      console.log(error);
    }
    return null;
  });
}

/**
 * 加载应用数据
 *
 * @author chitanda
 * @date 2022-07-20 20:07:50
 * @return {*}  {Promise<void>}
 */
async function loadAppData(): Promise<void> {
  const res = await ibiz.net.get('/appdata');
  if (res.ok) {
    ibiz.appData = res.data;
  }
}

/**
 * 加载组织数据
 *
 * @author chitanda
 * @date 2022-07-20 20:07:44
 * @return {*}  {Promise<void>}
 */
async function loadOrgData(): Promise<void> {
  const res = await ibiz.net.get(`/uaa/getbydcsystem/${ibiz.env.dcSystem}`);
  if (res.ok) {
    const orgDataItems = res.data;
    if (orgDataItems) {
      const [data] = orgDataItems;
      ibiz.orgData = data;
    }
  }
}

/**
 * 应用参数初始化
 *
 * @author chitanda
 * @date 2022-07-20 19:07:54
 * @return {*}  {Promise<void>}
 */
async function appInit(): Promise<void> {
  try {
    await loadOrgData();
    await loadAppData();
    await loadModel();
  } catch (error: any) {
    console.log(`应用参数初始化失败：${error.message}`);
  }
}

/**
 * 认证拦截器
 *
 * @author chitanda
 * @date 2022-07-20 16:07:45
 * @export
 * @param {AuthGuardProps} props
 * @return {*}  {JSX.Element}
 */
export function AuthGuard({ routes }: AuthGuardProps): JSX.Element {
  const local = useLocation();
  const routeNodes = useRoutes(routes);
  const [end, setEnd] = useState(false);
  const token = getToken();

  // 获取 AppData
  useEffect(() => {
    if (!token || end) {
      return;
    }
    appInit()
      .then(() => setEnd(true))
      .catch(() => setEnd(false));
  }, [token, end]);

  // 未认证跳转登录页面
  if (local.pathname.startsWith('/index') && !token) {
    return (
      <Navigate to={`/login?redirect=${encodeURIComponent(local.pathname)}`} />
    );
  }
  // appData 未获取完成，绘制空白页面
  if (end === false && local.pathname.startsWith('/index')) {
    return <div />;
  }
  return <Suspense fallback={false}>{routeNodes}</Suspense>;
}
